package com.syj.qdp.framework.security.config;

import com.syj.qdp.framework.security.core.filter.JwtTokenAuthenticateFilter;
import com.syj.qdp.framework.security.core.handler.DefaultAccessDeniedHandler;
import com.syj.qdp.framework.security.core.handler.DefaultAuthenticationEntryPoint;
import com.syj.qdp.framework.security.core.handler.DefaultLogoutSuccessHandler;
import com.syj.qdp.framework.security.core.service.SecurityAuthFrameworkService;
import com.syj.qdp.framework.web.handler.GlobalExceptionHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.annotation.Resource;

/**
 * @author Lyon
 */
@EnableConfigurationProperties(SecurityProperties.class)
public class SecurityAutoConfiguration {

    @Resource
    private SecurityProperties securityProperties;

    @Bean
    @ConditionalOnMissingBean
    public JwtTokenAuthenticateFilter jwtTokenAuthenticateFilter(SecurityAuthFrameworkService securityAuthFrameworkService, GlobalExceptionHandler globalExceptionHandler) {
        return new JwtTokenAuthenticateFilter(securityProperties, securityAuthFrameworkService, globalExceptionHandler);
    }

    @Bean
    @ConditionalOnMissingBean
    public AccessDeniedHandler defaultAccessDeniedHandler() {
        return new DefaultAccessDeniedHandler();
    }

    @Bean
    @ConditionalOnMissingBean
    public AuthenticationEntryPoint defaultAuthenticationEntryPoint() {
        return new DefaultAuthenticationEntryPoint();
    }

    @Bean
    @ConditionalOnMissingBean
    public LogoutSuccessHandler defaultLogoutSuccessHandler() {
        return new DefaultLogoutSuccessHandler();
    }

    /**
     * Spring Security 加密器
     * 考虑到安全性，这里采用 BCryptPasswordEncoder 加密器
     *
     * @see <a href="http://stackabuse.com/password-encoding-with-spring-security/">Password Encoding with Spring Security</a>
     */
    @Bean
    @ConditionalOnMissingBean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
